<template>
  <div id="boxContent">
    <div id="leftContent" class="leftArea">
      <template v-if="!isPdfPreview">
        <div class="note">长按并拖拽该签章到 pdf 内容区域，鼠标状态不为禁止时，放置即可盖章成功</div>
        <div id="OldSeal" class="sealOld" draggable="true" @dragstart="drag">
          <div class="pict">

          </div>
        </div>
      </template>
      <!--为克隆签章定义 dragover 和 drop 函数，是为了可以进行很小位置的移动-->
      <div id="cloneSeal" class="cloneSeal" draggable="true" @dragstart="dragClone" @dragover="allowDrop"
           @drop="drop" @dblclick="toDelete">
        <div class="pict">

        </div>
        <div id='icons' class="icon" @click="deleteNode">
          <span>删 除</span>
        </div>
      </div>
    </div>
    <div id="contentArea" class="centerArea" @dragover="allowDrop" @drop="drop">
      <VuePdf
          ref="wrapper"
          class="page"
          v-for="page in numPages"
          :key="page"
          src="https://sealzy.oss-cn-qingdao.aliyuncs.com/1649679994089.pdf"
          :page="page"
          style="width:100%;margin-left: 400px"
          :scale="1"/>
    </div>
    <div class="rightArea">
      <div class="toolGroup">
        <template v-if="!isPdfPreview">
          <div class="note">双击签章，点击底部的删除按钮即可进行删除，再双击签章，即可隐藏删除按钮</div>
          <el-button type="danger" >签 署</el-button>
        </template>
        <div class="page">第 {{ page }} / {{ numPages }} 页</div>
        <el-button type="primary" @click.stop="prePage">上一页</el-button>
        <el-button type="primary" @click.stop="nextPage">下一页</el-button>
        <div class="toolArea">
          <span>跳到</span>
          <el-input v-model="inputPage" @keyup.enter.native="pageChange"/>
          <span>页</span>
        </div>
      </div>
    </div>
  </div>

</template>

<script setup>
import { defineComponent, onMounted, reactive, ref } from 'vue';
import { VuePdf, createLoadingTask } from 'vue3-pdfjs/esm';

const page = ref(1) // 当前页
const numPages = ref(0) // 总页数
const inputPage = ref(1) // 输入的页码
const x = ref(0) //鼠标相对与div左边，上边的偏移
const y = ref(0)
const type = ref(0) // 0 原来的容器 1 克隆的容器
const positionPage = ref(1) // 最终定位
const positionX = ref(0)
const positionY = ref(0)
const isPdfPreview = ref(false) // 是否pdf预盖章成功预览模式

const pdfSrc = ref("https://sealzy.oss-cn-qingdao.aliyuncs.com/1649679994089.pdf")

// 获取 pdf 信息
onMounted(() => {
  const loadingTask = createLoadingTask(pdfSrc.value)
  loadingTask.promise.then((pdf) => {
    numPages.value = pdf.numPages
  })
  window.addEventListener('scroll', handleScroll, true);
})

// 滚动事件 滚动时更新页码
const handleScroll = () => {
  let scrollTop = getScrollTop() // 滚动高度
  let onePageHeight = getAttributeValue('page', 'height') // 单页面高度
  page.value = Math.round(scrollTop / onePageHeight) + 1
}

// 获取滚动高度
const getScrollTop = () => {
  let scroll_top = 0;
  if (document.documentElement && document.documentElement.scrollTop) {
    scroll_top = document.documentElement.scrollTop;
  } else if (document.body) {
    scroll_top = document.body.scrollTop;
  }
  return scroll_top;
}

// 滚动到固定位置
const goTo = (target) => {
  let scrollT = document.body.scrollTop || document.documentElement.scrollTop
  console.log(scrollT)
  if (scrollT > target) {
    let timer = setInterval(function () {
      let scrollT = document.body.scrollTop || document.documentElement.scrollTop
      let step = Math.floor(-scrollT / 6);
      document.documentElement.scrollTop = document.body.scrollTop = step + scrollT;
      if (scrollT <= target) {
        document.body.scrollTop = document.documentElement.scrollTop = target;
        clearTimeout(timer);
      }
    }, 20)
  } else if (scrollT === 0) {
    let timer = setInterval(function () {
      let scrollT = document.body.scrollTop || document.documentElement.scrollTop
      let step = Math.floor(300 / 3 * 0.7);
      document.documentElement.scrollTop = document.body.scrollTop = step + scrollT;
      if (scrollT >= target) {
        document.body.scrollTop = document.documentElement.scrollTop = target;
        clearTimeout(timer);
      }
    }, 20)
  } else if (scrollT < target) {
    let timer = setInterval(function () {
      let scrollT = document.body.scrollTop || document.documentElement.scrollTop
      let step = Math.floor(scrollT / 6);
      document.documentElement.scrollTop = document.body.scrollTop = step + scrollT;
      if (scrollT >= target) {
        document.body.scrollTop = document.documentElement.scrollTop = target;
        clearTimeout(timer);
      }
    }, 20)
  } else if (target === scrollT) {
    return false;
  }
}

// 上一页
const prePage = () => {
  let tempPage = page.value;
  tempPage = tempPage > 1 ? tempPage - 1 : 1;
  page.value = tempPage;
  changeScrollTop()
}

// 下一页
const nextPage = () => {
  let tempPage = page.value;
  tempPage = tempPage < numPages.value ? tempPage + 1 : numPages.value;
  page.value = tempPage;
  changeScrollTop()
}

// 根据输入的页码跳转页面
const pageChange = () => {
  let reg = /^[1-9]\d*$/
  if (!reg.test(inputPage.value)) {
    this.$message.error('请输入正确的页码')
    return
  }
  inputPage.value > numPages.value ? page.value = numPages.value : page.value = ~~inputPage.value
  inputPage.value < 1 ? page.value = 1 : page.value = ~~inputPage.value
  changeScrollTop()
}

// 根据页码变化修改页面滚动距离
const changeScrollTop = () => {
  console.log(document.getElementById('contentArea').offsetHeight)
  let onePageHeight = document.getElementById('contentArea').offsetHeight / numPages.value
  console.log(onePageHeight)
  let scrollTo = onePageHeight * (page.value - 1)
  goTo(scrollTo)
}

// 双击展示删除
const toDelete = () => {
  let iconItem = document.getElementById("icons");
  iconItem.style.opacity === 1 ? iconItem.style.opacity = 0 : iconItem.style.opacity = 1
}

// 删除节点
const deleteNode = () => {
  let cloneItem = document.getElementById("cloneSeal");
  let iconItem = document.getElementById("icons");
  iconItem.style.opacity = 0
  cloneItem.style.opacity = 0
  cloneItem.style.left = 0
  cloneItem.style.top = 0
}

// 允许放置在该区域
const allowDrop = (ev) => {
  ev.preventDefault();
}

// 开始拖动 原始印章
const drag = (e) => {
  type.value = 0
  let sealItem = document.getElementById("OldSeal");
  x.value = e.clientX - sealItem.offsetLeft;
  y.value = e.clientY - sealItem.offsetTop;
}

// 开始拖动 修改克隆印章的位置
const dragClone = (e) => {
  // 获取侧边栏菜单宽度
  // let menuWidth = document.querySelector('.avue-sidebar').offsetWidth
  let menuWidth = 20

  type.value = 1
  let scrollTop = getScrollTop() // 滚动高度
  let cloneItem = document.getElementById("cloneSeal");
  x.value = e.clientX - cloneItem.offsetLeft - menuWidth;
  y.value = e.clientY - (cloneItem.offsetTop - scrollTop) - 50;
  // console.log('-------------------------')
  // console.log('鼠标---'+ e.clientX, e.clientY )
  // console.log('签章----'+cloneItem.offsetLeft, cloneItem.offsetTop-scrollTop )
  // console.log('偏差值----'+this.x, this.y )
  // console.log('-------------------------')
  // console.log('-------------------------')
  // console.log('-------------------------')
  // console.log('-------------------------')
}

// 结束移动
const drop = (ev) => {
  ev.preventDefault();
  let scrollTop = getScrollTop() // 滚动高度
  let cloneItem = document.getElementById('cloneSeal') // 克隆印章
  let leftWidth = document.getElementById('leftContent').offsetWidth // 左边区域的宽度
  let sealWidth = document.getElementById('OldSeal').offsetWidth // 印章宽度
  let contentWidth = document.getElementById('contentArea').offsetWidth // 文章的宽度
  let moveX = ev.clientX - x.value; // 印章距离浏览器左边距离
  let moveY = ev.clientY - y.value; // 印章距离浏览器顶部距离
  // 计算印章距离当前页面的左右边距
  let pageMargin = getAttributeValue('page', 'marginBottom') // 页面边距
  let pageHeight = getAttributeValue('page', 'height') // 页面高度
  let page = parseInt((moveY + scrollTop) / ((pageHeight + pageMargin))) + 1 // 第几页
  let formula = (moveY + scrollTop) - (pageHeight + pageMargin) * (page - 1) // 公式计算出距离当前页面的顶部距离

  // 获取侧边栏菜单宽度
  // let menuWidth = document.querySelector('.avue-sidebar').offsetWidth
  let menuWidth = 20
  // 禁止印章放在 pdf 内容外部
  if ((moveX + sealWidth <= contentWidth + leftWidth) && moveX >= leftWidth) {
    cloneItem.style.opacity = 1
    cloneItem.style.left = (moveX - menuWidth) + 'px'
    cloneItem.style.top = (moveY + scrollTop - 50) + 'px'  // 50是面包屑高度
    positionX.value = moveX - leftWidth
    positionY.value = formula
    positionPage.value = page // 最终页码
    console.log(positionPage.value, positionX.value, positionY.value)
  }
}

// 获取节点的某个属性值 只适用于获取 px 相关数据
const getAttributeValue = (className, attr) => {
  let pageDiv = document.querySelector('.' + className);
  let attrsValue = getComputedStyle(pageDiv);
  let attrVal = attrsValue[attr]
  return Number(attrVal.substr(0, attrVal.length - 2)) // 截取掉 px
}

</script>

<style lang="scss" scoped>
#boxContent {
  min-height: 100%;
  display: flex;

  .pict{
    width: 50px;
    height: 50px;
    background-color: #006cff;
  }

  .leftArea {
    flex: 1;
    background-color: #ccc;

    .note {
      width: 180px;
      font-size: 14px;
      background-color: #909399;
      color: #fff;
      padding: 5px;
      position: fixed;
      top: 40%;
      left: 14%;
    }

    .sealOld {
      position: fixed;
      top: 50%;
      left: 15%;
    }

    .cloneSeal {
      opacity: 0;
      z-index: 100;
      position: absolute;
      top: 0;
      left: 0;

      .icon {
        text-align: center;
        background-color: #909399;
        font-size: 14px;
        padding: 2px 0;
        opacity: 0;

        span {
          color: #fff;
          cursor: pointer;
        }
      }
    }
  }

  .centerArea {
    background-color: #ccc;
  }

  .rightArea {
    flex: 1;
    background-color: #ccc;

    .note {
      width: 170px;
      font-size: 14px;
      background-color: #909399;
      color: #fff;
      padding: 5px;
      margin-bottom: 30px;
      /* position: fixed;
       top:30%;
       left:83%;*/
    }


    .toolGroup {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      position: fixed;
      top: 50%;
      left: 87%;
      transform: translate(-50%, -50%);

      .el-button {
        width: 120px;
        height: 32px;
        padding: 0;
        margin-bottom: 10px;
      }

      .el-button + .el-button {
        margin-left: 0
      }

      .page {
        margin-bottom: 10px;
      }

      .toolArea {
        display: flex;
        align-items: center;

        .el-input {
          width: 60px;
          margin: 0 10px;
        }
      }
    }
  }
}

</style>
<style>

</style>
